<!-- 展示 》 多选结构树 -->

<template>
  <el-form-item v-bind="formItem">
    <!-- 标签 -->
    <template v-if="formItem.label" #label>
      <slot name="label" :label="formItem.label">{{ formItem.label }}</slot>
    </template>

    <div :class="divClass">
      <EasyScroll :hasX="!multiRow">
        <slot v-if="hasPrefix" name="prefix">
          <span :class="`${className}-prefix`">{{ prefix }}</span>
        </slot>

        <slot :text="trans(model, backup)">{{ trans(model, backup) }}</slot>

        <slot v-if="hasSuffix" name="suffix">
          <span :class="`${className}-suffix`">{{ suffix }}</span>
        </slot>
      </EasyScroll>
    </div>
  </el-form-item>
</template>

<script>
// ============================== 导入依赖 ============================== //

import CORE from '@/CORE'
import mixShow from '../mixShow'
import ShowText from '../ShowText'
import UTIL from '../../form/FormTree/UTIL'

const name = 'ShowTreeMulti'

// ============================== 导出组件 ============================== //

export default {
  /**
   * 名称定义 (实际使用名称)
   */
  name,

  /**
   * 混入列表 (配置选项合并)
   */
  mixins: [mixShow],

  /**
   * 属性注册 (抽取以便查阅)
   */
  props: CORE.WEB[name],

  /**
   * 状态数据 (函数返回对象)
   */
  data() {
    return {
      model: [], // 内部绑定值
      backup: [], // 备用绑定值
      EMPTY: [], // 空值常量
    }
  },

  /**
   * 计算属性 (慎用箭头函数)
   */
  computed: {
    ...ShowText.computed,

    /**
     * ID 列表的映射
     */
    idListMap() {
      const { dict } = this
      return UTIL.getIdListMap({}, dict)
    },

    /**
     * 节点字典
     */
    nodeDict() {
      const { dict } = this
      return UTIL.getNodeDict([], dict)
    },
  },

  /**
   * 本地方法 (轻量重要在前)
   */
  methods: {
    /**
     * 是否不等 (可覆盖)
     */
    isDiff() {
      const { obj, prop, bindList, isMulti, model, join, backup, nodeDict, allId } = this

      // 判断 backup (有时要相等，无时要为空)
      if (isMulti && backup !== obj[bindList[1]]) return true
      if (!isMulti && backup !== '') return true

      // 判断 model (存在要都有字典)
      const valueList = allId ? (obj[prop] || []).slice(-1)[0] : join ? obj[prop] ? obj[prop].split(',') : [] : obj[prop] || []
      const valuesList = valueList.map((value) => nodeDict.find(([id]) => value === id))
      return model.join() !== (valuesList.some((values) => !values) ? '' : valuesList.join())
    },

    /**
     * 设置内部绑定值 (可覆盖)
     */
    setModel() {
      const { obj, prop, bindList, isMulti, join, nodeDict, allId } = this
      const valueList = allId ? (obj[prop] || []).slice(-1)[0] : join ? obj[prop] ? obj[prop].split(',') : [] : obj[prop] || []
      const valuesList = valueList.map((value) => nodeDict.find(([id]) => value === id))

      this.backup = isMulti ? obj[bindList[1]] || '' : ''
      this.model = valuesList.length && valuesList.some((values) => !values) ? [] : valueList
    },

    /**
     * 转换方法
     */
    trans(values, backupValue) {
      const { allName, idListMap, join, or, and, nodeDict, showIndex, empty } = this
      const valueList = join ? values ? values.split(',') : [] : values
      const valuesList = valueList.map((value) => nodeDict.find(([id]) => value === id))

      // 字典不存在
      if (valuesList.some((values) => !values)) return backupValue || empty

      // 非全路径名称
      if (!allName) return valuesList.map((values) => values[showIndex]).join(or)

      // 全路径名称
      const namesList = valueList.map((value) => {
        const idList = idListMap[value] || []
        const nameList = idList.map((id) => nodeDict.find((item) => item[0] === id)[showIndex] || empty)
        return nameList.join(and)
      })
      return namesList.join(or)
    },
  },
}
</script>
